var shell = require('shelljs');
var path = require('path');

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        copy: {
            prebuild: {
                files: [
                    {
                        flatten: true,
                        expand: true,
                        src: [
                            'bower_components/lodash/dist/lodash.js',
                            'bower_components/jquery/dist/jquery.js',
                            'bower_components/codemirror/lib/codemirror.js',
                            'bower_components/codemirror/mode/javascript/javascript.js',
                            'bower_components/codemirror/addon/hint/show-hint.js',
                            'bower_components/codemirror/addon/hint/javascript-hint.js',
                            'bower_components/angular/angular.js',
                            'bower_components/angular-bootstrap/ui-bootstrap-tpls.js',
                            // 'bower_components/bootstrap/dist/js/bootstrap.js',
                            // 'bower_components/bootstrap-ui-treeview/dist/tree-view.js',
                            // 'bower_components/bootstrap-treeview/dist/bootstrap-treeview.min.js',
                            'bower_components/angular-ui-codemirror/ui-codemirror.js',
                            'bower_components/neo4j-driver/lib/browser/neo4j-web.js'
                        ],
                        dest: 'lib/js/'
                    },
                    {
                        flatten: true,
                        expand: true,
                        src: [
                            'bower_components/angular/angular-csp.css',
                            'bower_components/bootstrap/dist/css/bootstrap.css',
                            'bower_components/bootstrap/dist/css/bootstrap-theme.css',
                            'bower_components/bootstrap-treeview/dist/bootstrap-treeview.min.css',
                            'bower_components/codemirror/lib/codemirror.css',
                            'bower_components/codemirror/addon/hint/show-hint.css'
                        ],
                        dest: 'lib/css/'
                    },
                    {
                        flatten: true,
                        expand: true,
                        src: ['bower_components/bootstrap/dist/fonts/*'],
                        dest: 'lib/fonts/',
                        filter: 'isFile'
                    }
                ]
            },
            release:{
                files:[
                    {
                        flatten: true,
                        expand: true,
                        cwd:'src',
                        src:['*.html'],
                        dest:'dist/'
                    },
                    {
                        flatten: true,
                        expand: true,
                        src: ['lib/fonts/*'],
                        dest: 'dist/fonts/'
                    },
                    {
                        flatten: true,
                        expand: true,
                        src: ['src/fonts/*'],
                        dest: 'dist/fonts/'
                    },
                    {
                        flatten: true,
                        expand: true,
                        cwd:'build/js',
                        src:['*.js'],
                        dest:'dist/js/'
                    }
                ]
            }
        },
        clean:{
            prebuild:{
                files: [
                    {
                        dot: true,
                        src: ["lib/**"]
                    }
                ]
            },
            build:{
                files: [
                    {
                        dot: true,
                        src: ["build/**"]
                    }
                ]
            },
            release:{
                files: [
                    {
                        dot: true,
                        src: ["dist/**"]
                    }
                ]
            }
        },
        concat:{
            css:{
                src:['lib/css/*.css','src/css/*.css'],
                dest:'build/css/main.css'
            },
            css_lib:{
                src:['lib/css/*.css'],
                dest:'build/css/main.css'
            },
            js_lib:{
                src:[
                    'lib/js/lodash.js',
                    'lib/js/jquery.js',
                    'lib/js/angular.js',
                    'lib/js/ui-bootstrap-tpls.js',
                    'lib/js/neo4j-web.js',
                    'lib/js/runtime.js'
                ],
                dest:'build/js/main.js'
            },
            core_es6:{
                src:['src/base/**/*.es6'],
                dest:'build/base/core.es6'
            },
            // fault_es6:{
            //     src:['src/fault/**/*.es6'],
            //     dest:'build/fault/app.es6'
            // },
            js:{
                src:['build/es6/apps.js','src/js/templates.js'],
                dest:'build/js/app.js'
            },
            es6:{
                src:['src/js/**/*.es6'],
                dest:'build/es6/apps.es6'
            }
        },
        cssmin:{
            build:{
                src:'build/css/main.css',
                dest:'dist/css/main.min.css'
            },
            lib:{
                src:'build/css/main.css',
                dest:'build/css/main.min.css'
            }
        },
        uglify:{
            options: {
                mangle: {
                    reserved: ['angular','$scope','jQuery','$compile','$sce','$timeout','$rootScope','$templateCache']  //不混淆该数组中的变量名
                },
                output:{
                    ascii_only: true,
                    comments: false //false（删除全部注释），some（保留@preserve @license @cc_on等注释）
                },
                sourceMap: true
            },
            build:{
                files:[
                    {
                        flatten: true,
                        expand: true,
                        src:['build/js/*.js'],
                        dest:'dist/js/',
                        ext: '.min.js'
                    }
                ]
            },
            lib:{
                files:[
                    {
                        flatten: true,
                        expand: true,
                        src:['build/js/main.js'],
                        dest:'build/js/',
                        ext: '.min.js'
                    }
                ]
            },
            core:{
                files:[
                    {
                        flatten: true,
                        expand: true,
                        src:['build/base/*.js'],
                        dest:'build/base/',
                        ext: '.min.js'
                    }
                ]
            },
            fault:{
                files:[
                    {
                        flatten: true,
                        expand: true,
                        src:['build/fault/*.js'],
                        dest:'build/fault/',
                        ext: '.min.js'
                    }
                ]
            }
        },
        html2js:{
            compile:{
                module:"template_base",
                singleModule:true,
                existingModule:true,
                src:['src/template/*.html'],
                dest:'src/js/templates.js'
            }
        },
        es6compiler:{
            options: {
                sourceMap: false,
                presets: ['es2015']
            },
            compile:{
                files: [{
                    expand:true,
                    cwd:'build/es6/',
                    src:['*.es6'],
                    dest:'build/es6/',
                    ext: '.js'
                }]
            },
            core:{
                files: [{
                    expand:true,
                    cwd:'build/base/',
                    src:['*.es6'],
                    dest:'build/base/',
                    ext: '.js'
                }]
            },
            fault:{
                files: [{
                    expand:true,
                    cwd:'build/fault/',
                    src:['*.es6'],
                    dest:'build/fault/',
                    ext: '.js'
                }]
            }
        }
    });

    function run(cmd, msg){
        grunt.verbose.writeln('Running: ' + cmd);
        var exitCode = shell.exec(cmd, {silent:false}).code;
        if (exitCode != 0) {
            grunt.fail.fatal("[ERROR] " + cmd, exitCode)
        }
        if (msg) grunt.log.ok(msg);
    }

    // Load the plugin that provides the "uglify" task.
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-cssmin');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-html2js');

    grunt.registerMultiTask('es6compiler', 'Use Babel compile es6 to es5.', function() {
        var options = this.options();
        var isWindows = process.platform === 'win32';
        var detectDestType = function(dest) {
            if (grunt.util._.endsWith(dest, '/')) {
                return 'directory';
            } else {
                return 'file';
            }
        };

        var unixifyPath = function(filepath) {
            if (isWindows) {
                return filepath.replace(/\\/g, '/');
            } else {
                return filepath;
            }
        };

        var isExpandedPair;
        // var dirs = {};

        this.files.forEach(function(filePair) {
            isExpandedPair = filePair.orig.expand || false;

            filePair.src.forEach(function (src) {
                src = unixifyPath(src);
                var dest = unixifyPath(filePair.dest);

                if (detectDestType(dest) === 'directory') {
                    dest = isExpandedPair ? dest : path.join(dest, src);
                }

                if (grunt.file.isDir(src)) {
                    grunt.file.mkdir(dest);
                    // dirs[dest] = src;
                } else {
                    var sc = 'babel '+src+' -o '+dest;

                    run(sc,sc);
                }
            });
        });
    });

    grunt.registerTask('build-lib',['concat:css_lib','concat:js_lib','cssmin:lib','uglify:lib']);
    grunt.registerTask('build-core',['concat:core_es6','es6compiler:core','uglify:core']);
    grunt.registerTask('build-fault',[
        // 'concat:fault_es6',
        'es6compiler:fault',
        'uglify:fault'
    ]);

    grunt.registerTask('prebuild',  ['clean:prebuild','copy:prebuild']);
    grunt.registerTask('build',['clean:build','concat:es6','es6compiler:compile','concat:css','concat:js_lib','concat:js']);
    grunt.registerTask('release',['cssmin:build','uglify:build','copy:release']);
    grunt.registerTask('compile',['html2js:compile','concat:es6','es6compiler:compile']);

    grunt.registerTask('build-all',['prebuild','html2js:compile','build','release']);
    // Default task(s).
    grunt.registerTask('default', ['build-all']);
};